/*
libndi.h
Copyright (C) 2020 VideoLAN

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef LIBNDI_LIBNDI_H
#define LIBNDI_LIBNDI_H

#include <libavutil/buffer.h>

typedef struct ndi_ctx ndi_ctx;

ndi_ctx *libndi_init(void);

enum ndi_data_type
{
    NDI_DATA_VIDEO,
    NDI_DATA_AUDIO,
    NDI_DATA_TEXT
};

typedef enum ndi_tally_state
{
    NDI_TALLY_NONE = 0,
    NDI_TALLY_PREVIEW,
    NDI_TALLY_LIVE
} ndi_tally_state_t;

#define NDI_NUM_DATA_POINTERS 16

typedef struct
{
    int data_type;

    /* Common */
    uint32_t fourcc;

    /* Video */
    uint8_t *data;
    int len;

    int fps_num;
    int fps_den;

    int width;
    int height;

    int picture_structure;

    /* Audio */
    AVBufferRef *buf[NDI_NUM_DATA_POINTERS];
    int samples;
    int num_channels;
    int sample_rate;
} ndi_data;

/* Discovery API */
typedef struct ndi_discovery_ctx ndi_discovery_ctx_t;
typedef struct ndi_discovery_item {
    char *name;
    char *ip;
    char *port;
} ndi_discovery_item_t;

static inline void libndi_discovery_item_destroy(ndi_discovery_item_t *item) {
    free(item->name);
    free(item->ip);
    free(item->port);
    free(item);
}

typedef void (*ndi_discovery_cb)(ndi_discovery_item_t *item, void *user_data);

ndi_discovery_ctx_t *libndi_discovery_init(ndi_discovery_cb callback, void *user_data);
int libndi_discovery_start(ndi_discovery_ctx_t *ctx);
int libndi_discovery_stop(ndi_discovery_ctx_t *ctx);
void libndi_discovery_destroy(ndi_discovery_ctx_t *ctx);

void libndi_list_sources(ndi_ctx *ndi_ctx);

typedef struct
{
    char *ip;
    char *port;
    ndi_tally_state_t initial_tally_state;
} ndi_opts;

int libndi_setup(ndi_ctx *ndi_ctx, ndi_opts *ndi_opts);

typedef void (*ndi_data_cb)(ndi_data *ndi_data, void *user_data);
void libndi_receive_data(ndi_ctx *ndi_ctx, ndi_data_cb callback, void *user_data);

void libndi_close(ndi_ctx *ndi_ctx);

#endif
